package com.zbec.mdrs.service;

import com.zbec.framework.core.service.SystemDictionaryService;
import com.zbec.framework.core.util.PageUtils;
import com.zbec.framework.core.vo.JqgridResponse;
import com.zbec.framework.core.vo.PageInfo;
import com.zbec.mdrs.constants.Constants;
import com.zbec.mdrs.entity.guarantee.Guarantee;
import com.zbec.mdrs.repository.jpa.GuaranteeDao;
import com.zbec.mdrs.util.DateUtils;
import com.zbec.mdrs.util.FilterUtils;
import com.zbec.mdrs.util.ResourceUtils;
import com.zbec.mdrs.util.ValidationUtils;
import com.zbec.mdrs.vo.FilterSearch;
import com.zbec.mdrs.vo.GuaranteeVo;
import com.zbec.mdrs.vo.SearchRuleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springside.modules.mapper.JsonMapper;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * Created by fxl on 2015/10/19.
 */
@Component
@Transactional
public class GuaranteeService {
    @Autowired
    private GuaranteeDao guaranteeDao;

    @Autowired
    private LogsService logsService;

    @Autowired
    private SystemDictionaryService systemDictionaryService;

    public JqgridResponse<GuaranteeVo> findAllGuarantee(GuaranteeVo vo,PageInfo pageInfo) {
        if(vo.getSkipInd()!= null && "Y".equals(vo.getSkipInd())){
            vo.setRecordStatus(Constants.RECORD_STATUS_ADDEDSKIPED);
        }else {
            vo.setRecordStatus(Constants.RECORD_STATUS_ADDED);
        }
        if(vo.getQuery_sjsj()!=null && vo.getQuery_sjsj()!=""){
            vo.setSjsj(vo.getQuery_sjsj().replace("-",""));
        }
        vo.setExistError(vo.getQuery_existError());

        FilterSearch search=  JsonMapper.nonDefaultMapper().fromJson(vo.getFilters(), FilterSearch.class);

        Specification<Guarantee> spec = buildSpecification(vo,search);
        List<GuaranteeVo> guaranteeVos=new ArrayList<GuaranteeVo>();
        Page<Guarantee>  guaranteeVoPage= guaranteeDao.findAll(spec, PageUtils.buildPageRequest(pageInfo));
        List<Guarantee> list=guaranteeVoPage.getContent();
        for (int i = 0; i <list.size(); i++) {
            guaranteeVos.add(convertGuarantee2VO(list.get(i)));
        }
        return  PageUtils.buildResponse(guaranteeVoPage,guaranteeVos);

    }

    private Specification<Guarantee> buildSpecification(GuaranteeVo vo,FilterSearch search) {
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if(!StringUtils.isEmpty(vo.getRecordStatus())){
            filters.put("recordStatus", new SearchFilter("recordStatus", SearchFilter.Operator.EQ, vo.getRecordStatus()));
        }
        if(!StringUtils.isEmpty(vo.getOrgId())){
            filters.put("orgId", new SearchFilter("orgId", SearchFilter.Operator.EQ, vo.getOrgId()));
        }
        if(!StringUtils.isEmpty(vo.getSjsj())){
            filters.put("sjsj", new SearchFilter("sjsj", SearchFilter.Operator.EQ, vo.getSjsj()));
        }
        if(!StringUtils.isEmpty(vo.getExistError())){
            filters.put("existError", new SearchFilter("existError", SearchFilter.Operator.EQ, vo.getExistError()));
        }

        if(vo.getSearch().equals("true")){
            List<SearchRuleVo> ruleList=search.getRules();
            for (int i = 0; i <ruleList.size(); i++) {
                SearchRuleVo rule=ruleList.get(i);
                if(rule.getField().equals("dbywzl")){
                    String dbywzl= systemDictionaryService.getSystemDictionaryValue(Constants.Constants_DBFS,rule.getData());
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), SearchFilter.Operator.EQ, dbywzl));
                }else if(rule.getField().equals("bz")){
                    String bz= systemDictionaryService.getSystemDictionaryValue(Constants.Constants_BZ,rule.getData());
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), SearchFilter.Operator.EQ, bz));
                }else  if(rule.getField().equals("wjfl")){
                    String wjfl= systemDictionaryService.getSystemDictionaryValue(Constants.Constants_WJFL,rule.getData());
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), SearchFilter.Operator.EQ, wjfl));
                }else  if(rule.getField().equals("dbksrq") || rule.getField().equals("dbdqrq")){
                    try {
                        filters.put(rule.getField(), new SearchFilter(rule.getField(), FilterUtils.getOperator(rule.getOp()), DateUtils.parseDate(rule.getData(), "yyyy-MM-dd") ));
                    }catch (Exception ex){
                        ex.printStackTrace();
                    }
                }
                else{
                    filters.put(rule.getField(), new SearchFilter(rule.getField(), FilterUtils.getOperator(rule.getOp()), rule.getData()));
                }
            }
        }
        Specification<Guarantee> spec = DynamicSpecifications.bySearchFilter(filters.values(), Guarantee.class);
        return spec;
    }

    public GuaranteeVo  convertGuarantee2VO(Guarantee entity){
        GuaranteeVo guaranteeVo = new GuaranteeVo();
        BeanUtils.copyProperties(entity, guaranteeVo, new String[]{"history"});
        guaranteeVo.setBzDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_BZ,guaranteeVo.getBz()));
        guaranteeVo.setWjflDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_WJFL,guaranteeVo.getWjfl()));
        guaranteeVo.setDbywzlDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_DBFS, guaranteeVo.getDbywzl()));
        return guaranteeVo;
    }

    public void  packagingBean(List<GuaranteeVo> list){
        for (int i = 0; i <list.size() ; i++) {
            GuaranteeVo guaranteeVo=list.get(i);
            guaranteeVo.setBzDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_BZ,guaranteeVo.getBz()));
            guaranteeVo.setWjflDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_WJFL,guaranteeVo.getWjfl()));
            guaranteeVo.setDbywzlDesc(systemDictionaryService.getSystemDictionaryDesc(Constants.Constants_DBFS, guaranteeVo.getDbywzl()));
        }
    }

    public JqgridResponse<GuaranteeVo> findGuaranteeByHistroy(String historyId,PageInfo pageInfo){
        Page<GuaranteeVo>  guaranteeVoPage= guaranteeDao.findGuaranteeByHistroy(historyId, PageUtils.buildPageRequest(pageInfo));
        packagingBean(guaranteeVoPage.getContent());
        return PageUtils.buildResponse(guaranteeVoPage, guaranteeVoPage.getContent());
    }


    public void  addGuarantee(Guarantee guarantee){
        if(guarantee.getRecordStatus() == null ||"".equals(guarantee.getRecordStatus())){
            guarantee.setRecordStatus(Constants.RECORD_STATUS_ADDED);
        }
        guarantee.setReportStatus(Constants.REPORT_STATUS_ACTIVE);
        guarantee.setSource(Constants.SOURCE_DRMAP);
        guarantee.setJrjgbm(Constants.BANK_CODE_F335);
        guaranteeDao.save(guarantee);
    }

    public void  updateGuarantee(GuaranteeVo guaranteeVo,String userIp){
        Guarantee guarantee=guaranteeDao.findOne(guaranteeVo.getId());
        guarantee.setBdbrzzjgdm(guaranteeVo.getBdbrzzjgdm());
        guarantee.setDydcfsje(guaranteeVo.getDydcfsje());

        ValidationUtils.validateData(Constants.BUSINESS_TYPE_GUARANTEE,guarantee);

        logsService.handleBuzLogData(userIp,"logs.type.27","logs.operation.update",true, ResourceUtils.getLocaleString("logs.27.update"));

    }

    public void ignoreGuarantee(String ids){

        if(ids.length()>0){
            String [] idArray=ids.split(",");
            for (int i = 0; i < idArray.length; i++) {
                Guarantee guarantee= guaranteeDao.findOne(Long.valueOf(idArray[i]));
                if(guarantee.getRecordStatus().equals(Constants.RECORD_STATUS_ADDED)){
                    guarantee.setRecordStatus(Constants.RECORD_STATUS_ADDEDSKIPED);
                }else{
                    guarantee.setRecordStatus(Constants.RECORD_STATUS_ADDED);
                }
            }

        }

    }

    public List<Guarantee> getActiveGuaranteeByYwMonth(final String sjsj,final Long orgId) {
        List<Guarantee> list=guaranteeDao.findAll(new Specification<Guarantee> (){
            @Override
            public Predicate toPredicate(Root<Guarantee> root,
                                         CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> predicate = new ArrayList<>();
                predicate.add(cb.equal(root.get("sjsj"), sjsj));
                predicate.add(cb.equal(root.get("recordStatus"),Constants.RECORD_STATUS_ADDED));
                predicate.add(cb.notEqual(root.get("reportStatus"), Constants.REPORT_STATUS_COMPLETED));
                if(orgId!=null){
                    predicate.add(cb.equal(root.get("orgId"),orgId));
                }
                Predicate[] pre = new Predicate[predicate.size()];
                return query.where(predicate.toArray(pre)).getRestriction();
            }
        });

        return list;
    }


}
